const express = require('express');
const router = express.Router();
const pool = require('../db');
const authMiddleware = require('../middleware/auth');
const { createLog } = require('../log');

// Public endpoint: allow unauthenticated clients (e.g. login page) to fetch the site name
// This route intentionally does NOT use authMiddleware and is placed before the parameterized /configs/:name route
router.get('/configs/网站名称', async (req, res) => {
  try {
    const [rows] = await pool.query(
      'SELECT id, config_name, config_value, remarks FROM atb_config WHERE config_name = ? LIMIT 1',
      ['网站名称']
    );
    if (rows && rows[0]) {
      return res.json({ config: rows[0], value: rows[0].config_value });
    }
    // not found: return a null value rather than 404 so clients can gracefully fallback
    res.json({ value: null });
  } catch (err) {
    console.error('Failed to fetch public site name:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

// GET /api/configs?page=1&limit=10&sort_by=&sort_order=
router.get('/configs', authMiddleware, async (req, res) => {
  try {
    // log page open
    createLog(req, { message: '打开配置列表', tp: 'view' });

    const page = Math.max(1, parseInt(req.query.page, 10) || 1);
    const limit = Math.max(1, parseInt(req.query.limit, 10) || 10);
    const offset = (page - 1) * limit;

    const allowedSorts = {
      id: 'id',
      config_name: 'config_name',
      config_value: 'config_value'
    };

    const sortBy = typeof req.query.sort_by === 'string' ? req.query.sort_by : null;
    let sortOrder = typeof req.query.sort_order === 'string' ? req.query.sort_order.toLowerCase() : null;
    if (sortOrder !== 'asc' && sortOrder !== 'desc') sortOrder = null;

    let orderClause = 'id DESC';
    if (sortBy && allowedSorts[sortBy]) {
      orderClause = `${allowedSorts[sortBy]} ${sortOrder === 'asc' ? 'ASC' : 'DESC'}`;
    }

    const [rows] = await pool.query(
      `SELECT id, config_name, config_value, remarks FROM atb_config ORDER BY ${orderClause} LIMIT ? OFFSET ?`,
      [limit, offset]
    );

    const [countRows] = await pool.query('SELECT COUNT(*) AS total FROM atb_config');
    const total = (countRows && countRows[0] && countRows[0].total) ? countRows[0].total : 0;

    res.json({ configs: rows, total });
  } catch (err) {
    console.error('Failed to fetch configs:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

// GET /api/configs/:name  (also supports numeric id fallback)
router.get('/configs/:name', authMiddleware, async (req, res) => {
  try {
    const identifier = req.params.name;
    if (!identifier) return res.status(400).json({ message: 'name required' });

    // try exact match by config_name first
    const [rowsByName] = await pool.query(
      'SELECT id, config_name, config_value, remarks FROM atb_config WHERE config_name = ? LIMIT 1',
      [identifier]
    );
    if (rowsByName && rowsByName[0]) {
      return res.json({ config: rowsByName[0], value: rowsByName[0].config_value });
    }

    // fallback: if identifier is numeric, try by id
    const id = parseInt(identifier, 10);
    if (!isNaN(id)) {
      const [rowsById] = await pool.query(
        'SELECT id, config_name, config_value, remarks FROM atb_config WHERE id = ? LIMIT 1',
        [id]
      );
      if (rowsById && rowsById[0]) {
        return res.json({ config: rowsById[0], value: rowsById[0].config_value });
      }
    }

    res.status(404).json({ message: 'Config not found' });
  } catch (err) {
    console.error('Failed to fetch config:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

// POST /api/configs
router.post('/configs', authMiddleware, async (req, res) => {
  try {
    const { config_name, config_value, remarks } = req.body || {};
    if (!config_name) return res.status(400).json({ message: 'config_name required' });
    if (typeof config_value === 'undefined') return res.status(400).json({ message: 'config_value required' });

    const [result] = await pool.query(
      'INSERT INTO atb_config (config_name, config_value, remarks) VALUES (?, ?, ?)',
      [config_name, config_value, remarks || null]
    );
    const insertId = result.insertId;
    const [rows] = await pool.query('SELECT id, config_name, config_value, remarks FROM atb_config WHERE id = ?', [insertId]);

    // log creation
    createLog(req, { message: `新增配置 ${config_name}`, tp: 'create', obj_json: JSON.stringify(rows[0] || { id: insertId, config_name }) });

    res.status(201).json({ config: rows[0] });
  } catch (err) {
    console.error('Failed to create config:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

// PUT /api/configs/:id
router.put('/configs/:id', authMiddleware, async (req, res) => {
  try {
    const id = parseInt(req.params.id, 10);
    if (isNaN(id)) return res.status(400).json({ message: 'Invalid id' });

    const fields = [];
    const params = [];
    if (Object.prototype.hasOwnProperty.call(req.body || {}, 'config_name')) {
      fields.push('config_name = ?'); params.push(req.body.config_name);
    }
    if (Object.prototype.hasOwnProperty.call(req.body || {}, 'config_value')) {
      fields.push('config_value = ?'); params.push(req.body.config_value);
    }
    if (Object.prototype.hasOwnProperty.call(req.body || {}, 'remarks')) {
      fields.push('remarks = ?'); params.push(req.body.remarks);
    }

    if (fields.length === 0) return res.status(400).json({ message: 'No fields to update' });

    params.push(id);
    const sql = `UPDATE atb_config SET ${fields.join(', ')} WHERE id = ?`;
    await pool.query(sql, params);

    const [rows] = await pool.query('SELECT id, config_name, config_value, remarks FROM atb_config WHERE id = ?', [id]);

    // log update
    createLog(req, { message: `编辑配置 id=${id}`, tp: 'update', obj_json: JSON.stringify(rows[0] || { id }) });

    res.json({ config: rows[0] });
  } catch (err) {
    console.error('Failed to update config:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

// DELETE /api/configs/:id
router.delete('/configs/:id', authMiddleware, async (req, res) => {
  try {
    const id = parseInt(req.params.id, 10);
    if (isNaN(id)) return res.status(400).json({ message: 'Invalid id' });
    await pool.query('DELETE FROM atb_config WHERE id = ?', [id]);

    // log delete
    createLog(req, { message: `删除配置 id=${id}`, tp: 'delete', obj_json: JSON.stringify({ id }) });

    res.json({ ok: true });
  } catch (err) {
    console.error('Failed to delete config:', err);
    res.status(500).json({ message: 'Server error' });
  }
});

module.exports = router;
